package com.cy.pj.sys.service.aspect;


import com.cy.pj.common.annoation.RequiredLog;
import com.cy.pj.sys.pojo.SysLog;
import com.cy.pj.sys.service.SysLogService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Date;

@Slf4j
@Aspect
@Component
public class SysLogAspect {
    @Pointcut("@annotation(com.cy.pj.common.annoation.RequiredLog)")
    public void doLog(){

    }
    @Around("doLog()")
    public Object doAround(ProceedingJoinPoint jp) throws Throwable{
        Long t1=System.currentTimeMillis();
        log.info("method start {}", t1);
        try {
            Object result = jp.proceed();
            Long t2=System.currentTimeMillis();
            log.info("method end   {}", t2-t1);
            doSaveLogInfo(jp, t2-t1, null);
            return result;
        }catch (Throwable e){
            Long t3=System.currentTimeMillis();
            log.info("method end   {}", t3-t1);
            doSaveLogInfo(jp,t3-t1 ,e);
            throw e;
        }
    }
    @Autowired
    private SysLogService sysLogService;
    private void doSaveLogInfo(ProceedingJoinPoint jp,Long time,Throwable e) throws NoSuchMethodException, JsonProcessingException {
        //获取用户行为日志
        String username="tony";
        String ip="192.168.100.11";
        Class<?> clazz = jp.getTarget().getClass();
        Signature signature = jp.getSignature();
        //System.out.println(signature.getClass().getName());
        MethodSignature methodSignature= (MethodSignature) signature;
       // System.out.println(methodSignature);
        Method targetMethod = clazz.getDeclaredMethod(methodSignature.getName(), methodSignature.getParameterTypes());
        //System.out.println(targetMethod);
        RequiredLog requiredLog = targetMethod.getAnnotation(RequiredLog.class);
        String operation=requiredLog.operation();
        String method=clazz.getName()+"."+targetMethod.getName();
        System.out.println(method);
        Object[] args=jp.getArgs();
        String params=new ObjectMapper().writeValueAsString(args);
        Integer status=e==null?0:1;
        String error=e==null?"":e.getMessage();
        //封装用户行为日志
        SysLog sysLog=new SysLog();
        sysLog.setUsername(username);
        sysLog.setIp(ip);
        sysLog.setCreatedTime(new Date());
        sysLog.setOperation(operation);
        sysLog.setMethod(method);
        sysLog.setParams(params);
        sysLog.setStatus(status);
        sysLog.setError(error);
        sysLog.setTime(time);
        //将日志写入到数据库
        log.info("user log {}", new ObjectMapper().writeValueAsString(sysLog));
        sysLogService.saveLog(sysLog);
    }
}
